package com.socialnetspace.web;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.socialnetspace.dao.IUserDAO;

@Service
@Transactional(readOnly = true)
public class CustomAuthenticationService implements UserDetailsService 
{
	
	private Log logger = LogFactory.getLog(this.getClass().getName());
	
	@Autowired
	IUserDAO userDAO;
	
	
	@Override
	public UserDetails loadUserByUsername(String username) 
			throws UsernameNotFoundException {
		
		logger.info("Loading user with name "+username);
		
		try {
			com.socialnetspace.domain.User domainUser = userDAO.findUserByUsername(username);
			
			boolean enabled = true;
			boolean accountNonExpired = true;
			boolean credentialsNonExpired = true;
			boolean accountNonLocked = true;
			
			if(domainUser==null) {
				logger.info("No user found with username \'"+username+"\'");
				throw new UsernameNotFoundException("User " + username + " not found.");
			}
			
			return new User(
					domainUser.getUsername(), 
					domainUser.getPassword().toLowerCase(),
					enabled,
					accountNonExpired,
					credentialsNonExpired,
					accountNonLocked,
					getAuthorities(domainUser.getRole()));
		} 
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	
	public Collection<? extends GrantedAuthority> getAuthorities(String role) {
		List<GrantedAuthority> authList = getGrantedAuthorities(getRoles(role));
		return authList;
	}
	
	
	public List<String> getRoles(String role) {
		
		List<String> roles = new ArrayList<String>();
		
		if(role.equals("ROLE_USER")) {
			roles.add("ROLE_USER");
		}
		else if(role.equals("ROLE_ADMIN")) {
			roles.add("ROLE_USER");
			roles.add("ROLE_ADMIN");
		}
		
		return roles;
	}
	
	
	public static List<GrantedAuthority> getGrantedAuthorities(List<String> roles) {
		
		List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
		for (String role : roles) {
			authorities.add(new SimpleGrantedAuthority(role));
		}
		return authorities;
	}

}
